package com.syys.privacy.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.TextRange;
import com.syys.common.config.WeCatConfig;
import com.syys.common.utils.DateUtils;
import com.syys.common.utils.StringUtils;
import com.syys.privacy.domain.PrivacyInfoUse;
import com.syys.privacy.domain.QaAnswer;
import com.syys.privacy.domain.QaPrivacy;
import com.syys.privacy.mapper.PrivacyInfoUseMapper;
import com.syys.privacy.service.IQaAnswerService;
import com.syys.privacy.service.IQaPrivacyService;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.ResourceUtils;

import javax.mail.internet.MimeMessage;
import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Classname WordUtil
 * @Description TODO
 * @Date 2021/7/15 19:53
 * @Created by ys
 */
public class WordUtil {

    private int chapter_num = 1;

    private PrivacyInfoUseMapper iPrivacyInfoUseService;
    private IQaPrivacyService iQaPrivacyService;
    private JavaMailSender mailSender;
    private IQaAnswerService iQaAnswerService;

    public WordUtil(PrivacyInfoUseMapper privacyInfoUseMapper, IQaPrivacyService iQaPrivacyService, IQaAnswerService iQaAnswerService, JavaMailSender mailSender) {
        this.iPrivacyInfoUseService = privacyInfoUseMapper;
        this.iQaPrivacyService = iQaPrivacyService;
        this.iQaAnswerService = iQaAnswerService;
        this.mailSender = mailSender;
    }

    public void initData(long id) {
        QaPrivacy qaPrivacy = iQaPrivacyService.selectQaPrivacyById(id);
        PrivacyInfoUse privacyInfoUse = new PrivacyInfoUse();
        privacyInfoUse.setPrivacyId(qaPrivacy.getPrivacyId());
        List<PrivacyInfoUse> privacyInfoUses = iPrivacyInfoUseService.selectPrivacyInfoUseList(privacyInfoUse);

        // 生成第二章节数据
        Document document1 = new Document();
        Section section = document1.addSection();

        Paragraph paragraph1 = section.addParagraph();
        TextRange textRange = paragraph1.appendText("二、我们收集、使用个人信息的目的及范围");
        paragraph1.applyStyle(BuiltinStyle.Heading_3);
        textRange.getCharacterFormat().setFontSize(10);
        textRange.getCharacterFormat().setFontName("宋体");
        textRange.getCharacterFormat().setBold(true);

        createContent(section, "为符合国家法律法规规定和实现本政策所述的下述业务功能，我们会在遵循合法、正当、必要原则的前提下，收集和使用您在使用我们的服务过程中主动提供和因使用我们的服务而产生或需向第三方收集的下述个人信息。");

        privacyInfoUses.forEach(infoUse -> {
            chapter_num = 1;
            String field = "accountRegisterLogin";
            String title = chapter_num + ".账号注册与登陆";
            String content = "当您选择注册【APP名称】账号时，您需要主动向我们提供您本人设置的【content】。前述信息为必要信息，如果您不提供，您将无法完成注册。如果您仅使用产品浏览、搜索基本服务，您不需要进行注册以及提供前述信息。";
            createParagraph(PrivacyInfoUse::getAccountRegisterLogin, PrivacyInfoUse::getAccountRegisterLoginOther, infoUse, section, field, title, content);

            field = "realNameAuth";
            title = chapter_num + ".身份识别与实名认证";
            content = "为了识别您的身份，以及履行国家法律法规规定的实名认证义务，您需要向我们提供您的【content】。前述信息为进行身份认证的必要信息，如果您不提供，您将可能无法完成身份认证。";
            createParagraph(PrivacyInfoUse::getRealNameAuth, PrivacyInfoUse::getRealNameAuthOther, infoUse, section, field, title, content);

            field = "productDisplay";
            title = chapter_num + ".产品展示";
            content = "当您使用我们的产品进行浏览和搜索时，我们需要收集【content】，以便向您返回相应的页面或结果。";
            createParagraph(PrivacyInfoUse::getProductDisplay, PrivacyInfoUse::getProductDisplayOther, infoUse, section, field, title, content);

            if (StringUtils.isNotEmpty(infoUse.getPlaceOrder()) || (StringUtils.isNotEmpty(infoUse.getPlaceOrderTable()) && !"[]".equals(infoUse.getPlaceOrderTable())) || StringUtils.isNotEmpty(infoUse.getPlaceOrderOther())) {
                createTitle(section, chapter_num + ".下单");
                createContent(section, "当您预订、购买、使用各类产品或服务时，您需要像我们提供必要的信息才能完成相应产品的预订、购买或使用，这些产品和对应所需的信息包括：");

                String placeOrderTable = infoUse.getPlaceOrderTable();
                if (StringUtils.isNotEmpty(placeOrderTable) && !"[]".equals(placeOrderTable)) {
                    JSONArray placeOrderTableArray = JSONArray.parseArray(placeOrderTable);
                    List<List<String>> data = new ArrayList<>();
                    placeOrderTableArray.forEach(placeOrderRow -> {
                        List<String> row = new ArrayList<>();
                        JSONObject placeOrderObj = (JSONObject) placeOrderRow;
                        row.add(Objects.toString(placeOrderObj.get("productName")));
                        row.add(Objects.toString(placeOrderObj.get("informationType")));
                        data.add(row);
                    });
                    String[] header = {"自主产品名称", "所需个人信息类型"};
                    createTable(section, data, header);
                }

                content = "与此同时，为了满足相关法律法规的规定，我们将收集与上述订单相关的交易信息（【content】）。";
                createContent(section, content.replaceAll("【content】", getReplaceContent(PrivacyInfoUse::getPlaceOrder, PrivacyInfoUse::getPlaceOrderOther, infoUse, "placeOrder")));
                chapter_num++;
            }

            field = "paymentSettlement";
            title = chapter_num + ".支付结算";
            content = "当您购买产品或者服务进行支付结算时，您需要向我们提供【content】（具体以您选择的支付方式要求的为准）。";
            createParagraph(PrivacyInfoUse::getPaymentSettlement, PrivacyInfoUse::getPaymentSettlementOther, infoUse, section, field, title, content);

//            if ("1".equals(infoUse.getProductMailing())) {
//                createTitle(section, chapter_num + ".产品邮寄");
//                createContent(section, "当您购买产品需要使用邮寄商品服务时，您需要向我们提供收货人姓名、收件地址、电话号码信息，以便您的订单能够送达。");
//                chapter_num++;
//            }

            if ("1".equals(infoUse.getInvoiceIssuance())) {
                createTitle(section, chapter_num + ".发票开具");
                createContent(section, "如果您需要开具纸质或者电子发票，您需要提供包括发票抬头、税号在内的开票信息以及电子邮箱、收件人姓名、收件地址、电话号码信息，以便您的发票能够送达。");
                chapter_num++;
            }

            if ("1".equals(infoUse.getLegalCompliance())) {
                createTitle(section, chapter_num + ".法律合规");
                createContent(section, "为了满足《中华人民共和国网络安全法》《中华人民共和国电子商务法》等法律法规的要求，我们将收集您的网络访问日志、交易信息以及文章、留言、评论信息。请您注意的是，我们收集前述信息的具体类型以相关法律法规的要求为准，且这是为了满足法律法规的强制性要求，无需征得您的同意。");
                chapter_num++;
            }

//            if (StringUtils.isNotEmpty(infoUse.getTransactionSecurityQ1())) {
//                createTitle(section, chapter_num + ".交易安全保障");
//                content = "为了准确识别、预防攻击和保护您的账户安全（包括判断【transactionSecurityQ1】），在您使用产品的过程中，我们将自动收集部分设备信息或软件信息，具体包括：【transactionSecurityQ2】。";
//
//                String transactionSecurityQ1 = getReplaceContent(PrivacyInfoUse::getTransactionSecurityQ1, PrivacyInfoUse::getTransactionSecurityQ1Other, infoUse, "transactionSecurityQ1");
//                String transactionSecurityQ2 = getReplaceContent(PrivacyInfoUse::getTransactionSecurityQ2, PrivacyInfoUse::getTransactionSecurityQ2Other, infoUse, "transactionSecurityQ2");
//                createContent(section, content.replaceAll("【transactionSecurityQ1】", transactionSecurityQ1).replaceAll("【transactionSecurityQ2】", transactionSecurityQ2));
//
//                content = "请您注意我们收集的场景可能包括在【APP名称】切换到后台的情况下。上述信息的收集频次我们会基于安全和风控所需的最小频次进行收集和上传，在您每次打开APP时，我们会将唯一设备识别符IMEI, IMSI, MAC, Android ID的上传频次控制在【transactionSecurityNum】次以内。我们将通过访问权限最小化、访问日志记录、与订单信息分开存储与授权等安全措施来保护这些设备和软件信息。";
//                createContent(section, content.replaceAll("【transactionSecurityNum】", infoUse.getTransactionSecurityNum()));
//
//                chapter_num++;
//            }

            if ("1".equals(infoUse.getPersonalizedAnalysisPush())) {
                createTitle(section, chapter_num + ".个性化分析与推送");
                createContent(section, "为了向您提供更加准确、个性、流畅及便捷的服务，或者帮助我们评估、改善或者设计产品、服务或者运营活动，我们会对根据本政策收集的您的信息进行综合统计、分析加工。");
                createContent(section, "我们还可能根据前述信息向您提供营销活动通知、商业性电子信息或您可能感兴趣的内容、广告，如您不希望接受此类信息，可根据我们提供的方法进行选择退订或者关闭推荐。");
                chapter_num++;
            }

            if (StringUtils.isNotEmpty(infoUse.getCustomerService())) {
                field = "customerService";
                title = chapter_num + ".客户服务与投诉处理";
                content = "为了及时为您提供客户服务和响应您的疑问、建议、意见和投诉，同时为了保障平台用户权益，防止欺诈，我们的工作人员可能会收集您的【content】，用以核验您的身份。当您需要我们提供与您交易信息相关的客服和售后服务时，为了确认您说提供信息的准确性，我们的客服人员会查询您的交易信息。同时，为了保证服务质量，我们可能会对您与我们的客服人员的通话进行录音，并对您所提的要求、疑问、建议、意见和投诉内容进行记录。";
                createParagraph(PrivacyInfoUse::getCustomerService, PrivacyInfoUse::getCustomerServiceOther, infoUse, section, field, title, content);
                chapter_num++;
            }
        });

        // 敏感词汇加粗
        TextSelection[] textSelections = document1.findAllString("手机", false, false);
        if(textSelections != null){
            for (TextSelection selection : textSelections) {
                selection.getAsOneRange().getCharacterFormat().setBold(true);
            }
        }

        File path = null;
        try {
            path = new File(ResourceUtils.getURL("classpath:PrivacyPolicyTemplate.docx").getPath());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Document document = new Document(path.getPath());

        //遍历文档1中的所有子对象
        for (int i = 0; i < document1.getSections().getCount(); i++) {
            Section sectionTemp = document1.getSections().get(i);

            for (int j = 0; j < sectionTemp.getBody().getChildObjects().getCount(); j++) {
                Object object = sectionTemp.getBody().getChildObjects().get(j);

                //复制文档1中的正文内容添加到文档2
                document.getSections().get(0).getBody().getChildObjects().add(((DocumentObject) object).deepClone());
            }
        }

        //使用新文本替换文档中的指定文本
        document.replace("【品牌名称】", qaPrivacy.getBrandName(), false, true);
        document.replace("【APP名称】", qaPrivacy.getAppName(), false, true);
        document.replace("【公司名称】", qaPrivacy.getCompanyName(), false, true);
        document.replace("【联系电话】", qaPrivacy.getPhone(), false, true);
        document.replace("【电子邮件】", qaPrivacy.getEmail(), false, true);
        document.replace("【联系地址】", qaPrivacy.getContactAddress(), false, true);
        document.replace("【更新日期】", DateUtils.dateTimeNow("yyyy年MM月dd日"), false, true);
        String saveFilePath = WeCatConfig.getDownloadPath() + "/" + qaPrivacy.getPrivacyId() + "/" + qaPrivacy.getCompanyName() + "隐私政策.docx";
        File file = new File(saveFilePath);
        if(!file.exists()){
            file.mkdirs();
        }
        document.saveToFile(saveFilePath, FileFormat.Docx_2013);
        document.dispose();

        new Thread(() -> {
            sendMail(qaPrivacy, saveFilePath);
        }).start();
    }


    private void sendMail(QaPrivacy qaPrivacy, String saveFilePath) {
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom("13980152803@163.com");
            helper.setTo(qaPrivacy.getEmail());
            helper.setSubject("隐私政策邮件发送。。。。");
            helper.setText("测试测试测试。");
            FileSystemResource file1 = new FileSystemResource(new File(saveFilePath));
            helper.addAttachment(qaPrivacy.getCompanyName() + "隐私政策.docx", file1);
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            throw new RuntimeException("发送邮件错误！", e);
        }
    }

    private void createTable(Section section, List<List<String>> data, String[] header) {
        Table table = section.addTable(true);
        table.resetCells(data.size() + 1, header.length);
        table.getTableFormat().setLeftIndent(20);

        TableRow row = table.getRows().get(0);
        row.isHeader(true);
        row.setHeight(20);
        row.setHeightType(TableRowHeightType.Exactly);
        row.getRowFormat().setBackColor(Color.gray);
        for (int i = 0; i < header.length; i++) {
            row.getCells().get(i).getCellFormat().setVerticalAlignment(VerticalAlignment.Middle);
            Paragraph p = row.getCells().get(i).addParagraph();
            p.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
            TextRange range1 = p.appendText(header[i]);
            range1.getCharacterFormat().setFontName("宋体");
            range1.getCharacterFormat().setFontSize(10);
            range1.getCharacterFormat().setBold(true);
        }

        for (int r = 0; r < data.size(); r++) {
            TableRow dataRow = table.getRows().get(r + 1);
            dataRow.setHeight(25);
            dataRow.setHeightType(TableRowHeightType.Exactly);
            dataRow.getRowFormat().setBackColor(Color.white);
            for (int c = 0; c < data.get(r).size(); c++) {
                dataRow.getCells().get(c).getCellFormat().setVerticalAlignment(VerticalAlignment.Middle);
                TextRange range2 = dataRow.getCells().get(c).addParagraph().appendText(data.get(r).get(c));
                range2.getCharacterFormat().setFontName("宋体");
                range2.getCharacterFormat().setFontSize(10);
            }
        }
    }


    private String getReplaceContent(Function<PrivacyInfoUse, String> function1, Function<PrivacyInfoUse, String> function, PrivacyInfoUse infoUse, String field) {
        String contentLabel = function1.apply(infoUse);
        if (StringUtils.isEmpty(contentLabel)) {
            return "";
        }
        List<String> accountRegisterLoginList = Arrays.asList(contentLabel.split(","));
        List<QaAnswer> qaAnswers = iQaAnswerService.selectByCode(accountRegisterLoginList, field);


        List<String> collect = qaAnswers.stream().map(QaAnswer::getValue).collect(Collectors.toList());
        if (StringUtils.isNotEmpty(function.apply(infoUse))) {
            collect.add(function.apply(infoUse));
        }
        return StringUtils.join(collect, "、");
    }

    private void createParagraph(Function<PrivacyInfoUse, String> function1, Function<PrivacyInfoUse, String> function, PrivacyInfoUse infoUse, Section section, String field, String titleText, String... contents) {
        String contentLabel = function1.apply(infoUse);
        if (StringUtils.isNotEmpty(contentLabel)) {
            List<String> accountRegisterLoginList = Arrays.asList(contentLabel.split(","));
            List<QaAnswer> qaAnswers = iQaAnswerService.selectByCode(accountRegisterLoginList, field);
            List<String> collect = qaAnswers.stream().map(QaAnswer::getValue).collect(Collectors.toList());
            if (StringUtils.isNotEmpty(function.apply(infoUse))) {
                collect.add(function.apply(infoUse));
            }
            String contentText = StringUtils.join(collect, "、");
            createTitle(section, titleText);
            for (String content : contents) {
                createContent(section, content.replaceAll("【content】", contentText));
            }
            chapter_num++;
        }
    }

    private void createContent(Section section, String content) {
        Paragraph paragraphTemp = section.addParagraph();
        TextRange textRangeTemp = paragraphTemp.appendText(content);
        paragraphTemp.getFormat().setFirstLineIndent(20);
        textRangeTemp.getCharacterFormat().setFontSize(10);
        textRangeTemp.getCharacterFormat().setFontName("宋体");
    }

    private void createTitle(Section section, String titleText) {
        Paragraph paragraphTemp = section.addParagraph();
        TextRange textRangeTemp = paragraphTemp.appendText(titleText);
        paragraphTemp.getFormat().setFirstLineIndent(20);
        textRangeTemp.getCharacterFormat().setFontSize(10);
        textRangeTemp.getCharacterFormat().setFontName("宋体");
        textRangeTemp.getCharacterFormat().setBold(true);
    }


}
